import axios, { AxiosInstance, AxiosResponse,AxiosRequestConfig, AxiosError } from 'axios'
import qs from 'qs'
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus';
import { getToken } from '@/utils/cookies'
import store from '@/store'
import { settings } from '@/setting'

const baseURL: string =  process.env.VUE_APP_BASE_API || ''



const service: AxiosInstance = axios.create({
  // baseURL: process.env.VUE_APP_BASE_API, // url = baseURL + request url
  baseURL: window.location.protocol==="https:" ? baseURL.replace('http://','https://') : baseURL,
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 20000 // request timeout
})

// request interceptor
service.interceptors.request.use(
  (config: AxiosRequestConfig) =>{
    if (store.getters.token) {
      /* add your header token */
    }
    if (config.method === 'post' && config.data) {
      config.data = qs.stringify(config.data)
    }
    return config 
  },
  (error: AxiosError) => {
    console.log('request error:', error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  (response: AxiosResponse) =>{
    const res = response.data
    // 单独对blob的处理
    if(response.config.responseType == 'blob'){
      if(res.type.includes('application/json')){
        return Promise.reject('blob type is application/json!')
      }else{
        return Promise.resolve(res)
      }
    }
    if (res.code === 200 || res.code === 1) {
        return Promise.resolve(res)
    } else {
        const __text = getStatusText(res)
        return Promise.reject(__text)
    }
  },
  (error: AxiosError) => {
    console.log('response err:', error) // for debug
    return Promise.reject('请求失败，请刷新页面重试!')
  }
)

//get status code msg
const getStatusText = (response: AxiosResponse): string => {
  const code = response.status
  let message = response.msg || ''
  switch (code) {
    case 401:
      message = '用户没有权限!'
      break
    case 403:
      message = '访问被禁止!'
      break
    case 404:
      message = '网络请求错误,未找到该资源!'
      break
    case 500:
      message = '服务器错误,请联系管理员!'
      break
  }
  return message
}

const request = (options: AxiosRequestConfig) => {
  options.method = options.method || 'post' // 默认请求方式为POST
  
  if(!settings.isMock) {
    // 传入参数时自动携带 token && client: 'pc'
    const Data = options.method === 'get' ? 'params' : 'data'
    if(options[Data]) {
      options[Data].token = getToken()
      options[Data].client = options[Data].client ? options[Data].client : 'pc'
    }else{
      options[Data] = {
        token: getToken(),
        client: 'pc'
      }
    }
  }
 
  // 加载动画 ，默认开启 可自定义loading样式 ; loading = {  fullscreen: true } 全屏loading
  var loading: boolean | object = typeof options.loading === 'undefined' ? true : options.loading
  var loadingInstance: any
  if (loading) {
    loading = typeof loading === 'object' ? loading : {
        target: 'body',
        lock: true,
        text: '拼命加载中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
    }
    loadingInstance = ElLoading.service(loading)
  }

  return new Promise((resolve,reject) => {
      service.request(options).then(res =>{
        loadingInstance && loadingInstance.close()
        if(options.isShowMessage && res.msg) {
          ElMessage({
            showClose: true,
            message: res.msg,
            type: 'success',
            duration: 1000
          })
        }
        return resolve(res)
      }).catch(err =>{
        loadingInstance && loadingInstance.close()
        ElMessageBox.alert(err, '错误', {
          confirmButtonText: '确定',
          type: 'error',
          center: true
        })
        return reject({
          code: 0,
          msg: err
        })
      })
  })
}

export default request